package br.com.crednove.controle;

import br.com.crednove.dao.DAOCliente;
import br.com.crednove.dao.DAOImportacao;
import br.com.crednove.modelo.Access;
import br.com.crednove.modelo.Cliente;
import br.com.crednove.modelo.Excel;
import br.com.crednove.modelo.Importacao;
import br.com.crednove.paineis.PainelImportar;
import java.io.File;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

public class ControleImportar {

    //Interface
    private PainelImportar painel;
    //Boolean que muda status do botão confirmar
    private boolean novo;
    //Classe que controla excel
    private Excel excel;
    private Access access;
    private Importacao imp;
    //Campos encontrados, campos do banco 
    private int campos[];
    //DAO do banco
    private DAOCliente daoCliente;
    private DAOImportacao daoImportacao;
    public static final int SEM_VINCULO = -1;
    private final String EXTENSAO_IMPORTACAO = ".xls";
    private final String JFILECHOOSER_FILTRO_DESCRICAO = "Arquivos do Excel 97-2003 (.xls)";
    private final String JFILECHOOSER_TITULO = "Abrir";
    private final String STRING_OK = "OK";
    private final String STRING_CONFIRMAR = "Confirmar";
    private final String STRING_NOVO = "Novo";
    private final String STRING_TRES_PONTOS = "...";
    private final String STRING_SELECIONE_ARQUIVO = "Selecione o arquivo";
    private final String STRING_INFORME_NOME_BASE = "Informe o nome da base de dados";
    private final String tituloErroVinculo = "Atenção";
    private final String msgErroVinculo = "Este campo já está vinculado a uma das colunas encontradas";
    private final String tituloErroArquivo = "Erro com extensão do arquivo.";
    private final String msgErroArquivo = " Verifique se o arquivo selecionado é do pacote Office 2003 "
            + "ou anteriores";

    public ControleImportar(PainelImportar painel) {
        this.daoCliente = new DAOCliente();
        this.daoImportacao = new DAOImportacao();
        this.campos = new int[Cliente.campos.length];
        this.novo = false;
        this.painel = painel;
    }

    //"Listeners" dos eventos da Interface
    public void btnConfirmarEvento() {
        if (this.novo) {
            this.resetar();
        } else {
            //Trava interface
            this.painel.getBtnConfirmar().setEnabled(false);
            this.painel.getBtnSelecionar().setEnabled(false);
            this.painel.getBtnDesvincular().setEnabled(false);
            this.painel.getBtnFechar().setEnabled(false);
            this.painel.getJltCampos().setEnabled(false);
            this.painel.getRdbAccess().setEnabled(false);
            this.painel.getRdbExcel().setEnabled(false);
            this.novo = true;
            if (this.painel.getRdbExcel().isSelected()) {
                this.importarClientesExcel();
            } else {
                this.importarClientesAccess();
            }
        }
    }

    public void btnSelecionarEvento() {
        if (this.painel.getRdbExcel().isSelected()) {
            File arquivo;
            arquivo = this.selecionarArquivo();
            if (arquivo != null) {
                this.excel = new Excel();
                this.painel.getTxtArquivo().setText(arquivo.getPath());
                if (this.excel.abrirArquivo(arquivo)) {
                    this.iniciaCampos();
                    this.imp = new Importacao();
                    this.imp.setNome(arquivo.getName());
                    this.imp.setTipo("Excel");
                    this.importarColunasExcel();
                    //Interface
                    this.painel.getJltCampos().setEnabled(true);
                    this.painel.getJltCampos().setListData(Cliente.campos);
                    this.painel.getBtnConfirmar().setEnabled(false);
                } else {
                    JOptionPane.showMessageDialog(null, this.msgErroArquivo, this.tituloErroArquivo,
                            JOptionPane.ERROR_MESSAGE, null);
                }
            }
        } else {
            this.access = new Access(this.painel.getTxtArquivo().getText());
            if (this.access.conectar()) {
                JOptionPane.showMessageDialog(null, "Conectado com sucesso");
                this.iniciaCampos();
                this.importarColunasAccess();
                //System.out.println(this.access.totalColunas("emp01"));
                //System.out.println(this.access.totalRegistros("emp01"));
                //Interface
                this.painel.getJltCampos().setEnabled(true);
                this.painel.getJltCampos().setListData(Cliente.campos);
            } else {
                JOptionPane.showMessageDialog(null, "Erro ao conectar");
            }
        }
    }

    public void btnVincularEvento() {
        if (this.abilitaVinculo(this.painel.getJltCampos1().getSelectedIndex())) {
            this.campos[this.painel.getJltCampos().getSelectedIndex()] = this.painel.getJltCampos1().getSelectedIndex();
            //Interface
            this.painel.getJltCampos().clearSelection();
            this.painel.getJltCampos1().clearSelection();
            this.painel.getBtnVincular().setEnabled(false);
            this.painel.getJltCampos1().setEnabled(false);
            if (this.abilitaConfirmar()) {
                this.painel.getBtnConfirmar().setEnabled(true);
            }
        } else {
            JOptionPane.showMessageDialog(null, this.msgErroVinculo, this.tituloErroVinculo,
                    JOptionPane.WARNING_MESSAGE, null);
        }
    }

    public void btnDesvincularEvento() {
        this.campos[this.painel.getJltCampos().getSelectedIndex()] = SEM_VINCULO;
        //Interface
        this.painel.getJltCampos().clearSelection();
        this.painel.getJltCampos1().clearSelection();
        this.painel.getBtnDesvincular().setEnabled(false);
        this.painel.getBtnConfirmar().setEnabled(false);
    }

    public void btnFecharEvento(ControleInicio giControle) {
        this.resetar();
        giControle.mostraPainel(ControleInicio.painelHome);
    }

    public void jltCamposEvento() {
        if (!this.painel.getJltCampos().isSelectionEmpty()) {
            int indice = campos[this.painel.getJltCampos().getSelectedIndex()];
            if (indice == -1) {
                this.painel.getJltCampos1().setEnabled(true);
                this.painel.getJltCampos1().clearSelection();
                this.painel.getBtnDesvincular().setEnabled(false);
            } else {
                this.painel.getJltCampos1().setSelectedIndex(indice);
                this.painel.getJltCampos1().setEnabled(false);
                this.painel.getBtnVincular().setEnabled(false);
                this.painel.getBtnDesvincular().setEnabled(true);
            }
        }
    }

    public void jltCampos1Evento() {
        if (!this.painel.getJltCampos1().isSelectionEmpty()) {
            this.painel.getBtnVincular().setEnabled(true);
        }
    }

    public void rdbExcelEvento() {
        this.painel.getBtnSelecionar().setText(STRING_TRES_PONTOS);
        this.painel.getTxtArquivo().setText(STRING_SELECIONE_ARQUIVO);
        this.painel.getTxtArquivo().setEditable(false);
    }

    public void rdbAccessEvento() {
        this.painel.getBtnSelecionar().setText(STRING_OK);
        this.painel.getTxtArquivo().setText(STRING_INFORME_NOME_BASE);
        this.painel.getTxtArquivo().setEditable(true);
    }

    //Controle Excel
    private File selecionarArquivo() {
        JFileChooser seletorArquivo = new JFileChooser();
        seletorArquivo.setFileSelectionMode(JFileChooser.FILES_ONLY);
        seletorArquivo.setDialogTitle(JFILECHOOSER_TITULO);
        seletorArquivo.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.getName().toLowerCase().endsWith(EXTENSAO_IMPORTACAO) || file.isDirectory();
            }

            @Override
            public String getDescription() {
                return JFILECHOOSER_FILTRO_DESCRICAO;
            }
        });

        int i = seletorArquivo.showOpenDialog(painel);
        if (i == JFileChooser.APPROVE_OPTION) {
            return seletorArquivo.getSelectedFile();
        } else {
            return null;
        }
    }

    private void importarColunasExcel() {
        this.painel.getJltCampos1().setListData(this.excel.importaColunas());
    }

    private void importarClientesExcel() {
        new Thread() {
            public void run() {
                Calendar cl = Calendar.getInstance();
                int importados = 0;
                String mes = String.valueOf(cl.get(Calendar.MONTH) + 1);
                String dia = String.valueOf(cl.get(Calendar.DAY_OF_MONTH));
                if (mes.length() < 2) {
                    mes = "0" + mes;
                }
                if (dia.length() < 2) {
                    dia = "0" + dia;
                }
                imp.setData(cl.get(Calendar.YEAR) + "" + mes + dia);
                if (daoImportacao.insert(imp)) {
                    imp.setId(daoImportacao.getCodigoImportacao());
                    daoCliente.conectar();
                    painel.getJpbProgresso().setMinimum(0);
                    painel.getJpbProgresso().setMaximum(excel.getNumLinhasTotal()-1);
                    
                    for (int i = 0; i < excel.getNumFolhas(); i++) {
                        for (int j = 1; j < excel.getFolhas()[i].getRows(); j++) {
                            Cliente cliente = excel.importaCliente(i, j, campos);
                            cliente.setCodImportacao(imp.getId());
                            if(daoCliente.insert(cliente)){
                                importados++;
                            }
                            painel.getJpbProgresso().setValue(j);
                            painel.getLblStatus().setText(importados + " / " + painel.getJpbProgresso().getMaximum());
                        }
                    }

                    JOptionPane.showMessageDialog(null, "Clientes importados com sucesso");
                    painel.getBtnConfirmar().setEnabled(true);
                    painel.getBtnFechar().setEnabled(true);
                    painel.getBtnConfirmar().setText(STRING_NOVO);
                    imp.setNumClientes(importados);
                    daoCliente.desconectar();
                    daoImportacao.atualizaTerminado(imp.getId(), imp.getNumClientes(), true);
                }else{
                    JOptionPane.showMessageDialog(null, "Não foi possivel importar");
                }
            }
        }.start();
    }

    //Controle Access
    private void importarColunasAccess() {
        this.painel.getJltCampos1().setListData(this.access.importarColunas(this.access.importarTabelas()[0]));
    }

    private void importarClientesAccess() {
        new Thread() {
            public void run() {
                painel.getLblStatus().setText("Carregando Clientes...");
                if (access.carregarClientes(access.getTabelas().get(0))) {
                    painel.getJpbProgresso().setMinimum(0);
                    painel.getJpbProgresso().setMaximum((int) access.totalRegistros());
                    try {
                        for (int i = 1; access.getRs().next(); i++) {
                            daoCliente.insert(access.importarCliente(campos));
                            painel.getJpbProgresso().setValue(i);
                            painel.getLblStatus().setText("Importando... " + i + " / " + painel.getJpbProgresso().getMaximum());
                        }
                    } catch (SQLException ex) {
                        Logger.getLogger(ControleImportar.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    JOptionPane.showMessageDialog(null, "Cl"
                            + "ientes importados com sucesso");
                    painel.getBtnConfirmar().setEnabled(true);
                    painel.getBtnFechar().setEnabled(true);
                    painel.getBtnConfirmar().setText(STRING_NOVO);
                }
                access.desconectar();
            }
        }.start();
    }

    //Métodos de auxilio de lógica
    //Deixa todos os campos sem nenhuma vinculação
    private void iniciaCampos() {
        for (int i = 0; i < campos.length; i++) {
            this.campos[i] = SEM_VINCULO;
        }
    }

    //Verifica se todos os campos foram vinculados e abilita o botão confirmar
    private boolean abilitaConfirmar() {
        if (this.campos[Cliente.INDICE_CPF] != SEM_VINCULO) {
            return true;
        }
        return false;
    }

    //Verifica se o campo selecionado ja possui vinculo a partir do reusltado pode abilitar
    //o botão vincular
    private boolean abilitaVinculo(int valor) {
        for (int i = 0; i < this.campos.length; i++) {
            if (this.campos[i] == valor) {
                return false;
            }
        }
        return true;
    }

    //Reinicia tudo
    private void resetar() {
        this.novo = false;
        //Reseta vinculações
        this.iniciaCampos();
        //Reseta Interface
        painel.getLblStatus().setText("...");
        this.painel.getBtnConfirmar().setText(STRING_CONFIRMAR);
        this.painel.getBtnConfirmar().setEnabled(false);
        this.painel.getBtnSelecionar().setEnabled(true);
        this.painel.getRdbAccess().setEnabled(true);
        this.painel.getRdbExcel().setEnabled(true);
        this.painel.getTxtArquivo().setText("");
        this.painel.getJltCampos().setListData(new String[0]);
        this.painel.getJltCampos1().setListData(new String[0]);
        this.painel.getJpbProgresso().setValue(0);
        this.painel.getJpbProgresso().setStringPainted(true);
    }
}